package net.superdvach.network;

import java.io.*;
import java.util.*;

import net.i2p.I2PException;
import net.i2p.client.*;
import net.i2p.data.*;

public class I2PNetworkLayer implements NetworkLayer, I2PSessionListener {
	
	public I2PNetworkLayer(String destination) throws I2PException, IOException {
		m_client = I2PClientFactory.createClient();
		if(destination.isEmpty())
		{
			ByteArrayOutputStream outstream = new ByteArrayOutputStream();
			m_client.createDestination(outstream);
			m_destData = outstream.toByteArray();
		}
		else
		{
			m_destData = Base64.decode(destination);
		}
		ByteArrayInputStream instream = new ByteArrayInputStream(m_destData);
		m_session = m_client.createSession(instream, new Properties());
	}

	@Override
	public String layerType() {
		return "i2p";
	}

	@Override
	public NetworkAddress makeAddress(String str) {
		try {
			return new I2PNetworkAddress(str);
		} catch (DataFormatException e) {
			return null;
		}
	}

	@Override
	public void sendPacket(byte[] packet, NetworkAddress address) {
		I2PNetworkAddress addr = (I2PNetworkAddress)address;
		try {
			m_session.sendMessage(addr.destination(), packet);
		} catch (I2PSessionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public String humanReadableName() {
		return new String("i2p:" + m_session.getMyDestination().hashCode());
	}
	
	@Override
	public void addListener(NetworkMessageListener listener) {
		m_listeners.add(listener);
	}

	@Override
	public void removeListener(NetworkMessageListener listener) {
		m_listeners.remove(listener);		
	}
	
	@Override
	public void disconnected(I2PSession session) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void errorOccurred(I2PSession session, String message, Throwable error) {
		System.out.println("Error: " + message);
		
	}

	@Override
	public void messageAvailable(I2PSession session, int msgId, long size) {
		try {
			byte[] packet = session.receiveMessage(msgId);
			for(NetworkMessageListener listener : m_listeners) {
				listener.packet(packet);
			}
		} catch (I2PSessionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	@Override
	public void reportAbuse(I2PSession session, int severity) {
		// TODO Auto-generated method stub
		
	}

	I2PClient m_client;
	byte[] m_destData;
	I2PSession m_session;
	ArrayList<NetworkMessageListener> m_listeners;
}
